<template>
  <el-dialog :title="title" :visible.sync="visible" :modal="modal?modal:true" :width="width?width:'60%'" :before-close="cancel" :destroy-on-close="true"
    :close-on-click-modal="false" :append-to-body="appendToBody?appendToBody:false">
    <el-form ref="form" :model="formData" label-width="12%" :rules="rules">
      <el-form-item v-for="item in fields" :key="item.value" :label="item.label" :prop="item.value">

        <!-- 普通输入框 -->
        <el-input v-model="formData[item.value]" size="small"
          :placeholder="item.placeholder ? item.placeholder : '请输入' + item.label"
          v-if="!item.type || item.type == 'string'"
          :disabled="item.disabled"
          ></el-input>

        <!-- 密码框 -->
        <el-input v-model="formData[item.value]"  type="password"
          :placeholder="item.placeholder ? item.placeholder : '请输入' + item.label"
          v-if="item.type == 'password'"
          :disabled="item.disabled"
          ></el-input>

        <!-- 文本域 -->
        <el-input type="textarea" :rows="3" size="small"
          v-model="formData[item.value]"
          v-if="item.type == 'textarea'"
          :disabled="item.disabled"
          :paceholder="item.placeholder ? item.placeholder : '请输入' + item.label"
          ></el-input>

        <!-- 联级选择器 -->
        <el-cascader v-model="formData[item.value]" :options="item.options"
          :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label" v-if="item.type == 'cascader'"
          :show-all-levels="false" :props="{ emitPath: false, checkStrictly: true }" :disabled="item.disabled"/>
        
        <!-- 地区选择器 -->
        <AreaSelector
          v-if="item.type == 'areaSelector'" :value.sync="formData[item.value]" :disabled="item.disabled"
          ></AreaSelector>

        <!-- 图标选择器 -->
        <el-input v-model="formData[item.value]" :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label"
          v-if="item.type == 'icon'" :disabled="true">
          <template slot="prepend">
            <p class="form_icon_box" v-html="formData[item.value]"></p>
          </template>
          <template slot="append">
            <el-button @click="iconSelectorDisplay = true" :disabled="item.disabled">选择图标</el-button>
          </template>
        </el-input>
        <IconSelector :visible.sync="iconSelectorDisplay" :value.sync="formData[item.value]" v-if="item.type == 'icon'"></IconSelector>

        <!-- 单选 -->
        <el-radio v-model="formData[item.value]" v-if="item.type == 'radio'" v-for="option in item.options"
          :key="option.value" :label="option.value" :disabled="item.disabled" border>{{ option.label }}</el-radio>

        <!-- 计数器 -->
        <el-input-number v-model="formData[item.value]" v-if="item.type == 'number'" :min="0" :disabled="item.disabled"/>

        <!-- 下拉框 -- 单选 -->
        <el-select v-model="formData[item.value]"
          :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label" v-if="item.type == 'selector'"
          :disabled="item.disabled" filterable>
          <el-option v-for="i in item.options" :key="item.optionsValue ? i[item.optionsValue] : i.value"
            :label="item.optionsLabel ? i[item.optionsLabel] : i.label"
            :value="item.optionsValue ? i[item.optionsValue] : i.value">
          </el-option>
        </el-select>

        <!-- 日期选择器 -->
        <el-date-picker v-if="item.type == 'date'" v-model="formData[item.value]" type="date" 
        :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label"
        format="yyyy-MM-dd" value-format="yyyy-MM-dd">
        </el-date-picker>

        <!-- 下拉框 -- 多选 -->
        <MultipleSelector v-if="item.type == 'multipleSelector'" :value.sync="formData[item.value]" :label="item.label"
          :options="item.options" :optionsLabel="item.optionsLabel" :optionsValue="item.optionsValue" :placeholder="item.placeholder" :disabled="item.disabled"/>

        <!-- 菜单选择器 -->
        <MenuSelector v-if="item.type == 'menuSelector'" :menuValue.sync="formData[item.value]"/>

        <!-- 树形选择器 -- 单选 -->
        <treeselect v-if="item.type == 'treeSelector'" v-model="formData[item.value]" :options="item.options" :disabled="item.disabled"
          :show-count="true" :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label" />

        <!-- 图片选择器 -->
        <div class="imageSelector" v-if="item.type == 'imageSelector'" :disabled="true">
          <div v-if="formData[item.value]">
            <img :src="formData[item.value]" alt="">
            <div class="editIcon">
              <i class="el-icon-delete" @click="formData[item.value] = undefined"></i>
              <i class="el-icon-edit" @click="imageSelectorDisplay = true" ></i>
            </div>
          </div>
          <i v-else class="el-icon-plus" @click="imageSelectorDisplay = true"></i>
        </div>
        <ImageSelector :visible.sync="imageSelectorDisplay" :value.sync="formData[item.value]" v-if="item.type == 'imageSelector'"></ImageSelector>

        <!-- 图片选择器 - 多选 -->
        <div v-if="item.type == 'imagesSelector'" :disabled="true">
          <div v-if="formData[item.value]">
            <div class="imagesSelector images" v-for="(url, index) in formData[item.value].split(',')" :key="index"
              @click="delImage(item.value, index, url)" >
              <img :src="url" alt="">
              <div>
                <i class="el-icon-delete"></i>
              </div>
            </div>
          </div>
          <div class="imagesSelector" @click="imagesSelectorDisplay = true" >
            <i class="el-icon-plus"></i>
          </div>
        </div>
        <ImagesSelector :visible.sync="imagesSelectorDisplay" :value.sync="formData[item.value]" v-if="item.type == 'imagesSelector'"></ImagesSelector>

        <!-- 文件选择器 -->
        <el-input v-model="formData[item.value]" :placeholder="item.placeholder ? item.placeholder : '请选择' + item.label"
          v-if="item.type == 'fileSelector'" :disabled="true">
          <template slot="append">
            <el-button @click="iconSelectorDisplay = true" :disabled="item.disabled">选择文件</el-button>
          </template>
        </el-input>
        <FileSelector :visible.sync="iconSelectorDisplay" :value.sync="formData[item.value]"
          v-if="item.type == 'fileSelector'" ></FileSelector>

        <!-- 富文本编辑器 -->
        <Editor v-if="item.type == 'editor'" :value.sync="formData[item.value]"></Editor>

      </el-form-item>
      <!-- 插槽 -->
      <slot name="fieldsSlot"></slot>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <slot name="footerSlot"></slot>
      <el-button @click="cancel">取 消</el-button>
      <el-button :loading="saveLoading" type="primary" @click="submit">提 交</el-button>
    </span>
  </el-dialog>
</template>

<script>
const MenuSelector = () => import("./menuSelector.vue");
const MultipleSelector = () => import("./multipleSelector.vue");
const ImageSelector = () => import("./imageSelector.vue");
const ImagesSelector = () => import("./imagesSelector.vue");
const FileSelector = () => import("./fileSelector.vue");
const Editor = () => import("./editor.vue");
const AreaSelector = () => import("./areaSelector.vue");
const IconSelector = () => import("./iconSelector.vue");

import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";

export default {
  props: ["title", "visible", "fields", "formData", "cancelForm", "submitForm", "width", "modal", "appendToBody"],
  components: {
    MenuSelector,
    Treeselect,
    MultipleSelector,
    ImageSelector,
    ImagesSelector,
    FileSelector,
    Editor,
    AreaSelector,
    IconSelector,
  },
  data() {
    return {
      iconSelectorDisplay: false,
      imageSelectorDisplay: false,
      imagesSelectorDisplay: false,
      rules: {},
      saveLoading: false,
    }
  },
  watch: {
      watchFromData: {
          handler(visible) {
              if (visible) {
                  this.saveLoading = false;
              }
          }
      },
      watchRules: {
        handler() {
              this.getRules();
          }
      }
  },
  computed: {
    watchFromData() {
      return this.visible
    },
    watchRules(){
      return this.fields
    }
  },
  mounted() {
    this.getRules()
  },
  methods: {
    // 删除【图片选择器-多选】中已选择的图片
    delImage(field, index, url){
      let value = this.formData[field].split(",");
      let newValue = "";
      value.splice(index, 1);
      value.forEach((e, i)=>{
        if(i==0){
          newValue += e;
        }else{
          newValue += "," + e;
        }
      });
      this.formData[field] = newValue;
    },
    // 提取表单验证
    getRules() {
      this.rules = {};
      for (let i = 0; i < this.fields.length; i++) {
        if (this.fields[i].rules) {
          this.rules[this.fields[i].value] = this.fields[i].rules;
        }
      }
    },
    // 提交事件
    submit() {
      this.saveLoading = true;
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.submitForm();
        }else{
          this.saveLoading = false;
        }
      });
    },
    // 关闭事件
    cancel() {
      if (this.cancelForm != undefined) {
        this.cancelForm()
      } else {
        this.$emit('update:visible', false)
      }
      this.$nextTick(() => {
        this.$refs["form"].resetFields();
      });
    }
  },
};
</script>

<style lang="less">
.form_icon_box{
  height: 23px;
  svg{
    width: 23px;
    height: 23px;
  }
}
.imageSelector{
  width: 178px;
  height: 178px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  font-size: 28px;
  color: #8c939d;
  line-height: 178px;
  text-align: center;
  img{
    max-width: 178px;
    max-height: 178px;
  }
  .editIcon{
    position: absolute;
    width: 178px;
    height: 178px;
    top: 0;
    color: #fff;
    background-color: rgba(0,0,0,0.5);
    display: none;
  }
  i{
    cursor: pointer;
    margin: 0 10px;
  }
}
.imageSelector:hover{
  border-color: #409eff;
}
.imageSelector:hover .editIcon{
  display: block;
}
.imagesSelector{
  width: 178px;
  height: 178px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  font-size: 28px;
  color: #8c939d;
  line-height: 178px;
  text-align: center;
  float: left;
  margin: 0 5px 5px 0;
  img{
    max-width: 178px;
    max-height: 178px;
  }
}
.imagesSelector:hover{
  border-color: #409eff;
}
.images{
  position: relative;
  div{
    position: absolute;
    width: 178px;
    height: 178px;
    top: 0;
    color: #fff;
    background-color: rgba(0,0,0,0.5);
    display: none;
  }
}
.images:hover div{
  display: block;
}
</style>